import socket
import threading
import time

global server_on


def create_server_socket():
    """
    创建服务器Socket
    :return: server_socket(IPV4, UDP)
    """
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    host = "127.0.0.1"
    port = 1000
    server_socket.bind((host, port))
    server_socket.settimeout(10)
    print(f"Socket created, timeout: {server_socket.gettimeout()}")
    return server_socket


def server():
    global server_on
    server_socket = create_server_socket()
    while server_on:
        try:
            data, addr = server_socket.recvfrom(1024)
        except socket.timeout as e:
            print("server timeout!")
            continue
        print(f"message from {addr}")
        print(data.decode('utf-8'))
        try:
            server_socket.sendto("server data".encode('utf-8'), addr)
        except socket.timeout as e:
            print('reSend failed')
            continue
        server_on = False


def client():
    """
    客户端, 发送一次
    """
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    client_socket.settimeout(5)
    host = "127.0.0.1"
    port = 1000
    try:
        client_socket.sendto("wdnmd, I'm client".encode("utf-8"), (host, port))
        recv_bytes, addr = client_socket.recvfrom(1024)
        print(recv_bytes.decode("utf-8") + f" from {addr}")
    except ConnectionError as e:
        print("ConnectionError at client")
        print(e.args)


def main_testLocal():
    global server_on
    server_on = True
    if server_on:
        print("aaa")
    t_server = threading.Thread(target=server)
    t_server.start()
    t_client = threading.Thread(target=client)
    t_client.start()
    # t_breakTest = threading.Thread(target=test_break_flag)
    # t_breakTest.start()

    t_server.join()
    t_client.join()
    # t_breakTest.join()


def main_testKali():
    localIP = '192.168.180.1'
    destIP = '192.168.180.130'
    port = 1000
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sock.bind((localIP, port))
    for _ in range(5):
        print('send')
        sock.sendto("CBJCBJ".encode(), (destIP, port))
    data, addr = sock.recvfrom(1024)
    print(f"{data.decode()} from {addr}")


global flag


def br_send():
    global flag
    broadcast = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    # broadcast.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
    broadcast.bind(('192.168.180.1', 1000))
    host = '192.168.180.255'
    port = 1000
    # broadcast.settimeout(5)
    while flag:
        broadcast.sendto("CBJCBJ".encode(), (host, port))
        print("sended")
        time.sleep(1)


def br_recv():
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
    sock.bind(('', 1000))
    # sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sock.settimeout(5)
    data, addr = sock.recvfrom(1024)
    print(f"{data.decode()} from {addr}")


if __name__ == '__main__':
    main_testKali()
    # flag = True
    # t_server = threading.Thread(target=br_send)
    # t_server.start()
    # t_client = threading.Thread(target=br_recv)
    # t_client.start()
    # time.sleep(5)
    # flag = False
